﻿using System.Text.Json.Serialization;

namespace LightCAD.Core.Elements
{
    /// <summary>
    /// 双向无限的辅助线
    /// </summary>
    public class LcXLine : LcElement
    {
        public Vector2d StartPoint;
        public Vector2d Direction;
        public LcXLine()
        {
            this.Type = BuiltinElementType.XLine;
        }
        public LcXLine(Vector2d start, Vector2d dir)
        {
            this.StartPoint = start;
            this.Direction = dir;
        }

        public override LcElement Clone()
        {
            var clone = Document.CreateObject<LcXLine>();
            clone.Copy(this);
            clone.Initilize(this.Document);
            return clone;
        }

        public override void Copy(LcElement src)
        {
            base.Copy(src);
            var line = ((LcRay)src);
            this.StartPoint = line.StartPoint;
            this.Direction = line.Direction;
        }

        public void Set(Vector2d? startPoint = null, Vector2d? dir = null, bool fireChangedEvent = true)
        {
            //PropertySetter:Start,End
            if (!fireChangedEvent)
            {
                if (startPoint != null) this.StartPoint = startPoint.Value;
                if (dir != null) this.Direction = dir.Value;
            }
            else
            {
                bool chg_start = (startPoint != null && startPoint != this.StartPoint);
                if (chg_start)
                {
                    //OnPropertyChangedBefore(nameof(StartPoint), this.StartPoint, startPoint);
                    var oldValue = this.StartPoint;
                    this.StartPoint = startPoint.Value;
                    OnPropertyChangedAfter(nameof(StartPoint), oldValue, this.StartPoint);
                }
                bool chg_end = (dir != null && dir != this.Direction);
                if (chg_end)
                {
                    //OnPropertyChangedBefore(nameof(Direction), this.Direction, dir);
                    var oldValue = this.Direction;
                    this.Direction = dir.Value;
                    OnPropertyChangedAfter(nameof(Direction), oldValue, this.Direction);
                }
            }
        }

        public override Box2d GetBoundingBox()
        {
            var start = -(this.Direction * double.MaxValue);
            var end = this.Direction * double.MaxValue;
            return new Box2d(start, end);
        }

        public override bool IntersectWithBox(Polygon2d testPoly, List<RefChildElement> intersectChildren = null)
        {
            var thisBox = this.BoundingBox;
            if (!thisBox.IntersectWith(testPoly.BoundingBox))
            {
                //如果元素盒子，与多边形盒子不相交，那就可能不相交
                return false;
            }
            return GeoUtils.IsPolygonIntersectXLine(testPoly.Points, this);
        }

        public override bool IncludedByBox(Polygon2d testPoly, List<RefChildElement> includedChildren = null)
        {
            return false; //射线不可能被某一个包围盒完全包含
        }
    }
}